#include "networkdiagnosewidget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QClipboard>
#include <QApplication>

NetworkDiagnoseWidget::NetworkDiagnoseWidget(const ConnectionInfo &connInfo, const DeviceInfo &devInfo, QWidget *parent)
    : QDialog(parent), m_connInfo(connInfo), m_devInfo(devInfo)
{
    setWindowTitle(QString("%1（%2）网络诊断").arg(
        !connInfo.name.isEmpty() ? connInfo.name : devInfo.name,
        !connInfo.device.isEmpty() ? connInfo.device : devInfo.name));
    resize(520, 420);
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    QString ip = !connInfo.ipAddress.isEmpty() ? connInfo.ipAddress : devInfo.ipAddress;
    QString gw = !connInfo.gateway.isEmpty() ? connInfo.gateway : devInfo.gateway;
    QString dns = !connInfo.dns.isEmpty() ? connInfo.dns : devInfo.dns;
    QString mac = !connInfo.macAddress.isEmpty() ? connInfo.macAddress : devInfo.macAddress;
    m_baseInfoHtml = QString("<div style='font-size:13px;color:#222;padding-bottom:4px;'>"
        "<b>连接名称：</b>%1&nbsp;&nbsp; <b>设备名称：</b>%2<br>"
        "<b>IPv4地址：</b>%3&nbsp;&nbsp; <b>网关：</b>%4<br>"
        "<b>DNS：</b>%5&nbsp;&nbsp; <b>MAC：</b>%6"
        "</div>")
        .arg(!connInfo.name.isEmpty() ? connInfo.name : devInfo.name)
        .arg(!connInfo.device.isEmpty() ? connInfo.device : devInfo.name)
        .arg(ip.isEmpty() ? "--" : ip)
        .arg(gw.isEmpty() ? "--" : gw)
        .arg(dns.isEmpty() ? "--" : dns)
        .arg(mac.isEmpty() ? "--" : mac);
    summaryLabel = new QLabel(this);
    summaryLabel->setStyleSheet("font-weight:normal;font-size:15px;color:#2d8cf0;padding:8px;");
    summaryLabel->setTextFormat(Qt::RichText);
    summaryLabel->setText(m_baseInfoHtml + "<div style='color:#2d8cf0;'>请点击下方按钮开始诊断</div>");
    mainLayout->addWidget(summaryLabel);
    stepList = new QListWidget(this);
    stepList->setSelectionMode(QAbstractItemView::SingleSelection);
    mainLayout->addWidget(stepList);
    QHBoxLayout *btnLayout = new QHBoxLayout;
    retryButton = new QPushButton("重新诊断", this);
    copyButton = new QPushButton("复制报告", this);
    closeButton = new QPushButton("关闭", this);
    btnLayout->addWidget(retryButton);
    btnLayout->addWidget(copyButton);
    btnLayout->addWidget(closeButton);
    mainLayout->addLayout(btnLayout);
    process = new QProcess(this);
    diagnoseSteps << QString("ip addr show %1").arg(connInfo.device)
                  << "nmcli device status"
                  << "ip route"
                  << "cat /etc/resolv.conf"
                  << QString("ping -c 2 -I %1 8.8.8.8").arg(connInfo.device);
    stepTitles << "接口状态" << "设备状态" << "路由信息" << "DNS配置" << "外网连通性";
    stepRawOutputs = QStringList();
    for (int i = 0; i < diagnoseSteps.size(); ++i)
        stepRawOutputs << "";
    connect(retryButton, &QPushButton::clicked, this, &NetworkDiagnoseWidget::startDiagnose);
    connect(closeButton, &QPushButton::clicked, this, &QDialog::accept);
    connect(copyButton, &QPushButton::clicked, this, &NetworkDiagnoseWidget::onCopyReport);
    connect(stepList, &QListWidget::itemClicked, this, &NetworkDiagnoseWidget::onStepClicked);
    connect(process, &QProcess::readyReadStandardOutput, this, &NetworkDiagnoseWidget::handleProcessOutput);
    connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &NetworkDiagnoseWidget::handleProcessFinished);
    startDiagnose();
}

void NetworkDiagnoseWidget::startDiagnose() {
    summaryLabel->setText(m_baseInfoHtml + "<div style='color:#2d8cf0;'>正在诊断，请稍候...</div>");
    stepList->clear();
    stepRawOutputs = QStringList();
    for (int i = 0; i < diagnoseSteps.size(); ++i)
        stepRawOutputs << "";
    hasError = false;
    for (const QString &title : stepTitles) {
        QListWidgetItem *item = new QListWidgetItem(QIcon(":/icons/resources/view.png"), title + " ...");
        stepList->addItem(item);
    }
    currentStep = 0;
    runNextStep();
}

void NetworkDiagnoseWidget::runNextStep() {
    if (currentStep >= diagnoseSteps.size()) {
        showSummary();
        return;
    }
    process->start("/bin/bash", QStringList() << "-c" << diagnoseSteps[currentStep]);
}

void NetworkDiagnoseWidget::handleProcessOutput() {
    QByteArray data = process->readAllStandardOutput();
    stepRawOutputs[currentStep] += QString::fromLocal8Bit(data);
}

void NetworkDiagnoseWidget::handleProcessFinished(int, QProcess::ExitStatus) {
    // 分析本步结果
    QString result = stepRawOutputs[currentStep];
    QIcon icon;
    QString text = stepTitles[currentStep];
    bool ok = false;
    switch (currentStep) {
    case 0: // 接口状态
        ok = result.contains("state UP") || result.contains("state UP", Qt::CaseInsensitive);
        icon = QIcon(ok ? ":/icons/resources/net_connected.png" : ":/icons/resources/net_disconnected.png");
        text += ok ? "：已启用" : "：未启用/未连接";
        break;
    case 1: // 设备状态
        ok = result.contains("connected") || result.contains("已连接");
        icon = QIcon(ok ? ":/icons/resources/net_connected.png" : ":/icons/resources/net_disconnected.png");
        text += ok ? "：已连接" : "：未连接";
        break;
    case 2: // 路由信息
        ok = result.contains("default");
        icon = QIcon(ok ? ":/icons/resources/net_connected.png" : ":/icons/resources/net_disconnected.png");
        {
            QString gw = !m_connInfo.gateway.isEmpty() ? m_connInfo.gateway : m_devInfo.gateway;
            if (ok) {
                text += QString("：正在通过网关<%1>进行诊断").arg(gw.isEmpty() ? "--" : gw);
            } else {
                text += "：无默认路由";
            }
        }
        break;
    case 3: // DNS配置
        ok = result.contains("nameserver");
        icon = QIcon(ok ? ":/icons/resources/net_connected.png" : ":/icons/resources/net_disconnected.png");
        text += ok ? "：已配置DNS" : "：未配置DNS";
        break;
    case 4: // 外网连通性
        ok = result.contains("ttl") || result.contains("bytes from");
        icon = QIcon(ok ? ":/icons/resources/net_connected.png" : ":/icons/resources/net_disconnected.png");
        text += ok ? "：可访问外网" : "：无法访问外网";
        break;
    }
    if (!ok) hasError = true;
    updateStep(currentStep, text, icon);
    currentStep++;
    runNextStep();
}

void NetworkDiagnoseWidget::updateStep(int idx, const QString &result, const QIcon &icon) {
    auto *item = stepList->item(idx);
    if (item) {
        item->setText(result);
        item->setIcon(icon);
    }
}

void NetworkDiagnoseWidget::showSummary() {
    QString resultHtml;
    if (!hasError) {
        resultHtml = "<div style='color:green;'>网络诊断通过，一切正常！</div>";
    } else {
        resultHtml = "<div style='color:red;'>网络存在异常，请点击步骤查看详情并根据建议排查！</div>";
    }
    summaryLabel->setText(m_baseInfoHtml + resultHtml);
}

void NetworkDiagnoseWidget::onStepClicked(QListWidgetItem* item) {
    int idx = stepList->row(item);
    if (idx >= 0 && idx < stepRawOutputs.size()) {
        QMessageBox::information(this, stepTitles[idx], stepRawOutputs[idx].isEmpty() ? "无详细输出" : stepRawOutputs[idx]);
    }
}

void NetworkDiagnoseWidget::onCopyReport() {
    QString report = summaryLabel->text().remove(QRegExp("<[^>]*>")) + "\n";
    for (int i = 0; i < stepTitles.size(); ++i) {
        report += QString("[%1] %2\n%3\n").arg(i+1).arg(stepTitles[i], stepRawOutputs[i]);
    }
    QApplication::clipboard()->setText(report);
    QMessageBox::information(this, "复制报告", "诊断报告已复制到剪贴板！");
} 